package com.yaowk.system.controller;

import com.feizhou.swagger.annotation.Api;
import com.feizhou.swagger.annotation.ApiOperation;
import com.feizhou.swagger.annotation.Param;
import com.feizhou.swagger.annotation.Params;
import com.jfinal.aop.Before;
import com.jfinal.aop.Clear;
import com.jfinal.kit.Kv;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.tx.Tx;
import com.xiaoleilu.hutool.util.ArrayUtil;
import com.yaowk.common.constant.ServiceCode;
import com.yaowk.common.controller.BaseController;
import com.yaowk.event.event.UserEvent;
import com.yaowk.event.model.UserModel;
import com.yaowk.system.common.Constant;
import com.yaowk.system.model.Role;
import com.yaowk.system.model.User;
import com.yaowk.system.model.UserRole;
import com.yaowk.system.shiro.TokenKit;
import com.yaowk.system.validator.UserIdValidator;
import net.dreamlu.event.EventKit;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresPermissions;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @authc yaowk
 * 2017/6/28
 */
@RequiresAuthentication
@RequiresPermissions("system:user")
@Before(UserIdValidator.class)
@Api(url = "/system/user", description = "用户管理，需权限system:user", tag = "User")
public class UserController extends BaseController {

    public UserController() {
        module = Constant.MODULE_NAME;
    }

    @Clear(UserIdValidator.class)
    @ApiOperation(url = "/{userId}", description = "查看用户详情")
    public User index() {
        Integer id = getParaToInt();
        User user = User.dao.findByIdLoadColumns(id, "id,username");
        user.setPassword(null);
        renderJson(user);
        return user;
    }

    @Clear(UserIdValidator.class)
    @ApiOperation(url = "/list", description = "查看下级用户列表")
    @Params({
            @Param(name = "pageNumber", description = "当前页", dataType = "Integer"),
            @Param(name = "pageSize", description = "页面大小", dataType = "Integer")
    })
    public Page<User> list() {
        Kv condition = Kv.by("status != ", User.DELETE).set(" parentId = ", TokenKit.getUserId());
        Page<User> page = User.dao.paginate(getPage(), condition);
        for (User user : page.getList()) {
            user.setPassword(null);
        }
        renderJson(page);
        return page;
    }

    @Before(Tx.class)
    @Clear(UserIdValidator.class)
    @RequiresPermissions("system:user:add")
    @ApiOperation(url = "/add", description = "添加下级用户，需权限system:user:add", httpMethod = "post")
    @Params({
            @Param(name = "username", description = "用户名", required = true),
            @Param(name = "password", description = "密码", required = true)
    })
    public User add() {
        User user = getBean(User.class, "", true);
        user.setParentId(TokenKit.getUserId());
        user.save();
        user.setPassword(null);
        UserModel userModel = new UserModel();
        userModel.setId(user.getId());
        EventKit.post(UserEvent.ADD_USER, new UserEvent(userModel));
        renderJson(user);
        return user;
    }

    @Before(Tx.class)
    @RequiresPermissions("system:user:edit")
    @ApiOperation(url = "/edit/{userId}", description = "修改下级用户，需权限system:user:edit", httpMethod = "post")
    @Params({
            @Param(name = "password", description = "密码", required = true)
    })
    public User edit() {
        User user = getBean(User.class, "", true);
        user.setId(getParaToInt());
        user.update();
        user.setPassword(null);
        renderJson(user);
        return user;
    }

    @Before(Tx.class)
    @RequiresPermissions("system:user:delete")
    @ApiOperation(url = "/delete/{userId}", description = "删除下级用户，需权限system:user:delete")
    public void delete() {
        Integer userId = getParaToInt();
        new User().setId(userId).delete();
        UserModel userModel = new UserModel();
        userModel.setId(userId);
        EventKit.post(UserEvent.DELETE_USER, new UserEvent(userModel));
        renderSuccess();
    }

    @Before(Tx.class)
    @RequiresPermissions("system:user:roleEdit")
    @ApiOperation(url = "/roleEdit/{userId}", description = "修改角色和用户关系，需权限system:user:roleEdit", httpMethod = "post")
    @Params({
            @Param(name = "roleId", description = "角色id", dataType = "Integer[]")
    })
    public void roleEdit() {
        Integer userId = getParaToInt();
        Integer[] roleIds = getParaValuesToInt("roleId");
        Kv condition = Kv.by("userId = ", userId);
        List<UserRole> userRoles = UserRole.dao.find(condition);
        for (UserRole userRole : userRoles) {
            userRole.delete();
        }
        if (ArrayUtil.isNotEmpty(roleIds)) {
            for (Integer roleId : roleIds) {
                new UserRole().setUserId(userId).setRoleId(roleId).save();
            }
        }
        renderSuccess();
    }

    @ApiOperation(url = "/roleList/{userId}", description = "查询用户角色列表")
    @Params({
            @Param(name = "userId", description = "用户id", dataType = "Integer")
    })
    public void roleList() {
        Integer userId = getParaToInt();
        List<UserRole> userRoles = UserRole.dao.find(Kv.by("userId = ", userId));
        Set<Integer> roleIds = new HashSet<>();
        for (UserRole userRole : userRoles) {
            roleIds.add(userRole.getRoleId());
        }
        List<Role> roles = Role.dao.find(Kv.by("createUserId = ", TokenKit.getUserId()));
        for (Role role : roles) {
            if (roleIds.contains(role.getId())) {
                role.put("checked", true);
            } else {
                role.put("checked", false);
            }
        }
        renderJson(roles);
    }

    @ApiOperation(url = "/passwordEdit", description = "修改密码", httpMethod = "post")
    @Params({
            @Param(name = "password", description = "密码"),
            @Param(name = "rePassword", description = "重复密码")
    })
    public void passwordEdit() {
        String password = getPara("password");
        String rePassword = getPara("rePassword");
        if (StrKit.isBlank(password)) {
            renderFail(ServiceCode.ERROR, getMsg("password_empty"));
            return;
        }
        if (!password.equals(rePassword)) {
            renderFail(ServiceCode.ERROR, getMsg("password_rePassword_diff"));
            return;
        }
        User user = new User();
        user.setId(TokenKit.getUserId())
                .setPassword(password)
                .update();
        renderSuccess();
    }
}
